package com.amigo.online.provider.user.service.impl;

import java.time.Instant;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.amigo.online.common.base.service.BaseService;
import com.amigo.online.common.core.response.StatusCode;
import com.amigo.online.common.param.result.UserInfo;
import com.amigo.online.common.util.SmsUtil;
import com.amigo.online.common.util.StringUtils;
import com.amigo.online.provider.user.common.GlobalController;
import com.amigo.online.provider.user.exception.SmsException;
import com.amigo.online.provider.user.mapper.VerificationCodeMapper;
import com.amigo.online.provider.user.model.entity.VerificationCode;
import com.amigo.online.provider.user.service.VerificationCodeService;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional(rollbackFor = Exception.class)
public class VerificationCodeServiceImpl extends BaseService<VerificationCode> implements VerificationCodeService {

    @Resource
    private VerificationCodeMapper verificationCodeMapper;

    @Override
    public boolean sendSmsCode(String mobilephone, String countryCode, Integer type) {
        if (verificationCodeMapper.getMobilephoneFiveMinutesCount(mobilephone, countryCode) >= 3) {
            throw new SmsException(StatusCode.SMS_CODE_MULTI);
        }
        String code = StringUtils.generateVerificationCode(4);
        VerificationCode vcode = new VerificationCode();
        vcode.setMobilephone(mobilephone);
        vcode.setCountryCode(countryCode);
        vcode.setCode(code);
        vcode.setType(type);
        vcode.setStatus(1);
        long nowMilliSeconds = System.currentTimeMillis();
        long nowSeconds = nowMilliSeconds / 1000;
        vcode.setCreatedTime(nowSeconds);
        vcode.setUpdatedTime(nowSeconds);
        if (verificationCodeMapper.insert(vcode) <= 0) {
            return false;
        }
        SmsUtil.send(countryCode, mobilephone, "checkcode", new String[]{code});
        return true;
    }

    @Override
    public boolean checkSmsCode(String mobilephone, String code, Integer type) {
//		VerificationCode vcode = verificationCodeMapper.getByCode(mobilephone, code, type);
        Example example = new Example(VerificationCode.class);
        example.createCriteria()
                .andCondition("status = ", 1)
                .andCondition("mobilephone = ", mobilephone)
                .andCondition("type = ", type)
                .andCondition("code = ", code)
                .andCondition("unix_timestamp(now()) - created_time <= 300");
        List<VerificationCode> vcodeList = verificationCodeMapper.selectByExample(example);
        if (vcodeList == null || vcodeList.size() == 0) {
            throw new SmsException(StatusCode.SMS_CODE_ERROR);
        }

        long nowSeconds = Instant.now().getEpochSecond();
        for (VerificationCode vcode : vcodeList) {
            vcode.setStatus(2);
            vcode.setUpdatedTime(nowSeconds);
        }
        verificationCodeMapper.batchUpdateStatus(vcodeList);
        return true;
    }

    @Override
    public String getMobilephoneCountryCode(String mobilephone, String code, Integer type) {
        VerificationCode vcode = verificationCodeMapper.getCountryCodeByCode(mobilephone, code, type);
        if (vcode == null) {
            return null;
        }
        return vcode.getCountryCode();
    }

    @Override
    public boolean sendSmsForUserUpdatePassword() {
        UserInfo loginedUser = GlobalController.getNowUser();
        return sendSmsCode(loginedUser.getMobilephone(), loginedUser.getCountryCode(), 3);
    }

    @Override
    public String checkSmsCodeAndGetCountryCode(String flag, String code, int type) {
        VerificationCode vcode = verificationCodeMapper.getByCode(flag, code, type);
        if (vcode == null) {
            throw new SmsException(StatusCode.SMS_CODE_ERROR);
        }
        vcode.setStatus(2);
        long nowMilliSeconds = System.currentTimeMillis() / 1000;
        vcode.setUpdatedTime(nowMilliSeconds);
        if (verificationCodeMapper.updateByPrimaryKeySelective(vcode) <= 0) {
            throw new SmsException(StatusCode.SMS_CODE_UPDATE_EXCEPTION);
        }
        return vcode.getCountryCode();
    }

}
